﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace RepX.Web.SessionState
{
    /// <summary>
    /// Helper library of common type conversions.
    /// </summary>
    public partial class Convert
    {
        public static bool ToBoolean(object o)
        {
            if (o is System.DBNull || o == null) return false;
            else return System.Convert.ToBoolean(o);
        }

        public static byte[] ToByteArray(object o)
        {
            if (o is System.DBNull || o == null) return null;
            else if (o is string) return Encoding.UTF8.GetBytes((string)o);
            else if (o is byte[]) return (byte[])o;
            else if (o is byte) return new byte[] { (byte)o };
            else if (o is sbyte) return new byte[] { (byte)o };

            new System.Exception(string.Format("Unsupported conversion from type {0} to byte[]", o.GetType().ToString()));
            return null;
        }

        public static byte[] ToByteArray(Int64 n)
        {
            return ToByteArray((ulong)n);
        }

        public static byte[] ToByteArray(ulong n)
        {
            return ToByteArray(n, 8);
        }

        public static byte[] ToByteArray(ulong n, int Length)
        {
            List<byte> b = new List<byte>();

            do
            {
                // Add byte
                b.Add((byte)(n & 0xFF));

                // Shift 8
                n >>= 8;
            }
            while (n > 0 || b.Count < Length);

            // Need to reverse as bytes are in wrong order
            byte[] final = b.ToArray();
            Array.Reverse(final);

            return final;
        }

        public static System.DateTime? ToDateTimeNullable(object o)
        {
            if (o is System.DBNull || o == null) return null;
            else if (o is string && (string)o == string.Empty) return null;
            else return ToDateTime(o);
        }

        public static System.DateTime? ToDateTimeNullable(object o, IFormatProvider provider)
        {
            if (o is System.DBNull || o == null) return null;
            else if (o is string && (string)o == string.Empty) return null;
            else return ToDateTime(o, provider);
        }

        public static System.DateTime ToDateTime(object o)
        {
            if (o is System.DBNull || o == null) return new System.DateTime();
            else if (o is System.Int64) return new System.DateTime((Int64)o);
            else return System.Convert.ToDateTime(o);
        }

        public static System.DateTime ToDateTime(object o, IFormatProvider provider)
        {
            if (o is System.DBNull || o == null) return new System.DateTime();
            else if (o is System.Int64) return new System.DateTime((Int64)o);
            else return System.Convert.ToDateTime(o, provider);
        }

        public static Int32? ToInt32Nullable(object o)
        {
            if (o is System.DBNull || o == null) return null;
            else if (o is string && (string)o == string.Empty) return null;
            else return ToInt32(o);
        }

        public static Int32 ToInt32(object o)
        {
            return ToInt32(o, 0);
        }

        public static Int32 ToInt32(object o, int defaultValue)
        {
            if (o is System.DBNull) return defaultValue;
            else if (o is Nullable) return defaultValue;
            else if (o is byte[]) return ToInt32((byte[])o);
            else if (o is string && ((string)o) == string.Empty) return defaultValue;
            else return System.Convert.ToInt32(o);
        }

        // Uneven conversion
        public static int ToInt32(byte[] o)
        {
            //if (o.Length == 8) return System.Convert.ToInt64(o);

            int Result = 0;
            foreach (byte b in o)
            {
                Result <<= 8;
                Result += b;
            }

            return Result;
        }

        public static string ToString(object o)
        {
            if (o is System.DBNull || o == null) return string.Empty;
            else if (o is byte[]) return Encoding.UTF8.GetString((byte[])o);
            else return System.Convert.ToString(o);
        }
    }
}
